package com.dingpeikeji.quickdeer.modules.pay.web;

import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alipay.util.AlipayNotify;
import com.dingpeikeji.quickdeer.core.common.config.Global;
import com.dingpeikeji.quickdeer.core.modules.orders.entity.TOrders;
import com.dingpeikeji.quickdeer.core.modules.orders.entity.TOrdersOut;
import com.dingpeikeji.quickdeer.core.modules.orders.service.TOrdersOutService;
import com.dingpeikeji.quickdeer.core.modules.orders.service.TOrdersService;
import com.dingpeikeji.quickdeer.core.modules.realsche.service.TRealscheService;
import com.dingpeikeji.quickdeer.mobile.service.TripCounselorService;
import com.dingpeikeji.quickdeer.modules.realsche.service.FRealscheService;
import com.dingpeikeji.quickdeer.modules.rentproduct.entity.ShareRentproduct;
import com.dingpeikeji.quickdeer.modules.rentproduct.service.ShareProductService;
import com.dingpeikeji.quickdeer.modules.rentproduct.service.TCargotypeService;
import com.dingpeikeji.quickdeer.modules.sms.entity.Sms;
import com.dingpeikeji.quickdeer.modules.sms.service.SmsApi;


/**
 * 支付宝支付的时候提示页面和结果页面
 * @author wuhao
 *
 */
@Controller
@RequestMapping("alipay")
public class AlipayCommonPageController {
	
	private Logger logger = LoggerFactory.getLogger(getClass());
	
	@Autowired
	private FRealscheService fRealscheService;
	@Autowired
	private TRealscheService tRealscheService;
	@Autowired
	private ShareProductService shareProductService;
	@Autowired
	private TOrdersOutService tOrdersOutService;
	@Autowired
	private TOrdersService tOrdersService;
	@Autowired
	private TripCounselorService tripCounselorService;

	@SuppressWarnings("rawtypes")
	@RequestMapping("notify")
	public void notifyUrl(HttpServletRequest request, HttpServletResponse response) throws Exception{
		logger.debug("支付宝支付回调通知");
		//获取支付宝POST过来反馈信息
		Map<String,String> params = new HashMap<String,String>();
		Map requestParams = request.getParameterMap();
		logger.debug("回调的参数={}", requestParams.toString());
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i]
						: valueStr + values[i] + ",";
			}
			//乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
			//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
			params.put(name, valueStr);
		}
		//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
		//商户订单号
		//String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
		String out_trade_no = params.get("out_trade_no");
		//支付宝交易号
		//String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
		String trade_no = params.get("trade_no");
		logger.debug("trade_no={}", trade_no);
		
		//String total_fee = new String(request.getParameter("total_fee").getBytes("ISO-8859-1"),"UTF-8");
		String total_fee = params.get("total_fee");
		if (StringUtils.isEmpty(total_fee)) {
			total_fee = params.get("total_amount");//手机端参数
		}
		logger.debug("total_fee={}", total_fee);
		//String buyer_id = new String(request.getParameter("buyer_id").getBytes("ISO-8859-1"),"UTF-8");
		String buyer_id = params.get("buyer_id");
		logger.debug("buyer_id={}", buyer_id);
		//交易状态
		//String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
		String trade_status = params.get("trade_status");
		logger.debug("trade_status={}", trade_status);
		PrintWriter out = response.getWriter();
		//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
		//if(AlipayNotify.verify(params)){//验证成功
			if(trade_status.equals("TRADE_FINISHED")){
				//判断该笔订单是否在商户网站中已经做过处理
				//如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
				//请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
				//如果有做过处理，不执行商户的业务程序
				//注意：
				//退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知
				out.print("success");
			} else if (trade_status.equals("TRADE_SUCCESS")){
				//判断该笔订单是否在商户网站中已经做过处理
				//如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
				//请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
				//如果有做过处理，不执行商户的业务程序
				//注意：
				//付款完成后，支付宝系统发送该交易状态通知
				//保存支付信息
				Map<String,Object> proResult = fRealscheService.proConfirmPay(Integer.parseInt(out_trade_no), Double.parseDouble(total_fee), trade_no, buyer_id, TOrders.PAY_WAY_ALIPAY);
				// 发短信给用户
				Sms sendSms = tOrdersService.composeSms(out_trade_no);
				Integer returnflag = (Integer)proResult.get("returnflag");
				//更改订单支付方式
				fRealscheService.updateOrderById(TOrders.PAY_WAY_ALIPAY,out_trade_no);
				TOrders tOrders = tOrdersService.get(out_trade_no);
				if(returnflag!=null && returnflag == 0) {
					if (sendSms == null){
						out.print("fail");
						return;
					} else {
						//拼车创建人支付成功,修改拼车产品,让该产品显示在AA拼车列表
						SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm");
						if (StringUtils.isNotEmpty(tOrders.getShareid())) {
							//修改产品状态
							ShareRentproduct shareRentproduct = shareProductService.getInfo(tOrders.getShareid());
							shareProductService.updateStatus(tOrders.getShareid(),"1");
							//修改shareproduct表中的已购买数量
							int alreadySell = tOrders.getPaycount()+shareRentproduct.getCurrentsell();
							shareProductService.updateSellAmount(tOrders.getShareid(),alreadySell+"");
							//AA拼车,人数达到要求,并且在截至日期之前,发送短信给全体订单用户,并修改拼车产品生效
							if (new Date().before(shareRentproduct.getEnddate())&&shareRentproduct.getMinamount().equals(alreadySell+"")) {
								int result = shareProductService.updateSuccess(shareRentproduct.getSid());
								if((alreadySell+"").equals(shareRentproduct.getMaxamount())){
									shareProductService.updateStatus(tOrders.getShareid(),"0");
								}
								if (result>0) {
									//处理整包车订单
									tRealscheService.updateStateForShare(tOrders.getRealscheid());
									//更新为未调度
									tRealscheService.updateDispstatusForShare(tOrders.getRealscheid());
									//发送短信给车队管理者
									Sms send = new Sms();
									//查询车队管理者
									send.setMobile(tOrders.getOffice().getOperatortel());
									send.setContent("您有一个新订单需要处理"+
											"，订单名:"+tOrders.getOrdername()+","+tOrders.getCartype().getTypename()+
											tOrders.getPurchasenum()+"辆，发车时间："+df.format(tOrders.getDepartdate())
											+"。为保护您和订车人的合法权益，请及时安排调度。如有任何疑问，欢迎咨询客服4009287733");
									SmsApi.sendSms(send);
									//发送短信给所有用户
									Sms sendUser = new Sms();
									//根据shareid查询购买拼车产品的手机
									List<String> telList = tOrdersService.getOrderTelByShareId(shareRentproduct.getSid());
									for (String tel : telList) {
										sendUser.setContent("【霞客约车】拼友你好，"+tOrders.getOrdername()+"已拼成功，订单不可退款。"
												+ "请于出行当天至少提前20分钟到达上车地点("+tOrders.getBoardaddr()+")，行车具体车牌号及司机信息将于出行前1-2天发送给本手机，若未收到请及时联系客服400－928－7733。");
										sendUser.setMobile(tel);
										System.out.println("购买用户的电话"+tel+"~~~~~~~~~~~~~~~~~~~");
										SmsApi.sendSms(sendUser);
									}
								}
							}
						}
						//如果订单是行程顾问则还要修改行程表中状态
						if("9".equals(tOrdersService.get(out_trade_no).getOrdertype())){
							tripCounselorService.updateTripState(out_trade_no,"1");
						}
						SmsApi.sendSms(sendSms);
						out.print("success");	//请不要修改或删除
					}
				}
			}
		/*}else{//验证失败
			out.print("fail");
		}*/
	}
	
	@SuppressWarnings("rawtypes")
	@RequestMapping("return")
	public void returnUrl(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception{
		logger.debug("支付宝支付返回页面");
		//获取支付宝GET过来反馈信息
		Map<String,String> params = new HashMap<String,String>();
		Map requestParams = request.getParameterMap();
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i]
						: valueStr + values[i] + ",";
			}
			//乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
			//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
			params.put(name, valueStr);
		}
		
		//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
		//商户订单号
		// String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
		//支付宝交易号
		// String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
		//交易状态
		String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");

		//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
		
		boolean verify_result = AlipayNotify.verify(params);
		
		if(verify_result){ // 验证成功
			if(trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")){
				//判断该笔订单是否在商户网站中已经做过处理
				//如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
				//如果有做过处理，不执行商户的业务程序
			}
			// 跳到成功页面
			String path = request.getContextPath();
			String basePath = new String();
			
			if (request.getServerPort() == 80)
				basePath = request.getScheme() + "://" + request.getServerName() + path;
			else
				basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path;
			response.sendRedirect(basePath+Global.getFrontPath()+"/paySuccess");
		}else{ // 验证失败
			response.setCharacterEncoding("UTF-8");
			response.getWriter().append("<html><head><meta charset=\"utf-8\"></head><body>非法访问！</body></html>");
		}
	}
	
	@SuppressWarnings("rawtypes")
	@RequestMapping("notifyRefound")
	public void notifyRefoundUrl(HttpServletRequest request, HttpServletResponse response) throws Exception{
		//获取支付宝POST过来反馈信息
		Map<String,String> params = new HashMap<String,String>();
		Map requestParams = request.getParameterMap();
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i]
						: valueStr + values[i] + ",";
			}
			//乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
			//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
			params.put(name, valueStr);
		}
		
		//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
		//批次号
		String batch_no = new String(request.getParameter("batch_no").getBytes("ISO-8859-1"),"UTF-8");
		//批量退款数据中转账成功的笔数
		String success_num = new String(request.getParameter("success_num").getBytes("ISO-8859-1"),"UTF-8");
		//批量退款数据中的详细信息
		// String result_details = new String(request.getParameter("result_details").getBytes("ISO-8859-1"),"UTF-8");

		//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
		PrintWriter out = response.getWriter();
		if(AlipayNotify.verify(params)){//验证成功
			// 每次退款都是一笔，所以success_num=1就是退款成功， success_num=0就是退款失败
			TOrdersOut query = new TOrdersOut();
			query.setBatchNo(batch_no);
			// 返回列表肯定不会为空，因为先有退款批次号才有通知
			List<TOrdersOut> ordersOutList = tOrdersOutService.findList(query);
			TOrdersOut orderOut = ordersOutList.get(0);
			if(orderOut.getNotifyed().equals(TOrdersOut.NOTIFED_NO)){ // 未处理通知
				/*orderOut.setNotifyed(TOrdersOut.NOTIFED_YES);
				if(success_num == "1") {
					orderOut.setRtnstatus(TOrdersOut.RTN_STATUS_SUCCESS);
				} else {
					orderOut.setRtnstatus(TOrdersOut.RTN_STATUS_FAIL);
				}
				tOrdersOutService.update(orderOut);*/
				if(success_num == "1") {
					fRealscheService.proConfirmRtn(batch_no);
					try {
						TOrders orders = tOrdersService.get(""+orderOut.getOrderid()); 
						Sms sms = new Sms();
						sms.setMobile(orders.getPayertel());
						sms.setContent("您购买的由"+orders.getOffice().getName()+"提供的用车订单（"+orders.getOrderid()+"）已取消，我们将根据预订规则将相应款项在3个工作日内返回您的支付账户。");
						SmsApi.sendSms(sms);
					} catch (Exception e) {
					}
				}
			}
			
			out.print("success");	//请不要修改或删除
		}else{//验证失败
			out.print("fail");
		}
	}
}
